#ifndef INO_H
#define INO_H

#include "types.h"

/* @(#)ino.h	1.1 */

/*
 * Inode structure as it appears in a disk block.
 */

struct dinode
{
	imode_t	di_mode;     	/* mode and type of file (see below) */
	short	di_nlink;    	/* number of links to file */
	id_x	di_uid;      	/* owner's user id */
	id_x	di_gid;      	/* inode's group id */
	off_x	di_size;     	/* number of bytes in file */
	byte  	di_addr[40];	/* disk block addresses (see below) */
	time_t	di_atime;   	/* time last accessed */
	time_t	di_mtime;   	/* time last modified */
	time_t	di_ctime;   	/* time created/changed */
};


#define	ROOTINO	((ino_x)2)	/* inode number of all roots */
/* Note: the first physical inode has number 1 !	 */
/* Inode 1 is the bad-block repository, disguised as a file */
/* Inode 2 is the ROOT directory of the filesystem */


#define	INSIZ	64	/* size of a dinode in bytes	*/
#define	INOPB	8	/* 8 inodes per disk block	*/


/* Handy convertion macro's */

/* convert an inumber to a disk address */
#define	itod(x)	(daddr_x)(((uint)((x)+15)>>3))

/* convert an inumber to a disk offset within a block */
#define	itoo(x)	(int)(((x)+15)&07)


/* encoding of inode type in di_mode (upper 4 of 16 bits) */
#define	X_IFMT	0170000		/* type of file (mask upper 4 bits) */
#define		X_IFIFO 0010000 /* FIFO special file */
#define		X_IFCHR	0020000	/* character special */
#define		X_IFMPC	0030000	/* multiplexed char special */
#define		X_IFDIR	0040000	/* directory */
#define		X_IFBLK	0060000	/* block special */
#define		X_IFMPB	0070000	/* multiplexed block special */
#define		X_IFREG	0100000	/* regular */

/* flags in di_mode (lower 12 bits of 16) */
#define	X_ISUID		0004000	/* set user id on execution */
#define	X_ISGID		0002000	/* set group id on execution */
#define	X_ISVTX		0001000	/* save swapped text even after use */

#define	X_IUREAD	0000400	/* read permission, owner */
#define	X_IUWRITE	0000200	/* write permission, owner */
#define	X_IUEXEC	0000100	/* execute/search permission, owner */

#define	X_IGREAD	0000040	/* read permission, group */
#define	X_IGWRITE	0000020	/* write permission, group */
#define	X_IGEXEC	0000010	/* execute/search permission, group */

#define	X_IOREAD	0000004	/* read permission, other */
#define	X_IOWRITE	0000002	/* write permission, other */
#define	X_IOEXEC	0000001	/* execute/search permission, other */


/*
 * the 40 address bytes:
 * 39 are used for 13 addresses of 3 bytes each.
 *			 plus one byte for padding.
 *
 * data layout:
 *	addr[0] = most-significant-byte   of daddr[0]
 *	addr[1] = middle-significant-byte of daddr[0]
 *	addr[2] = least-significant-byte  of daddr[0]
 *
 *	addr[3] = most-significant-byte   of daddr[1]
 *	addr[4] = middle-significant-byte of daddr[1]
 *	addr[5] = least-significant-byte  of daddr[1]
 *
 *	etc
 */

#ifndef NADDR
#define NADDR	13	/* no. of disk addresses in inode */
#endif


/*
 * Device numbers (addr[1],addr[2]) iff inode is a device
 */

/* given a dev_x, split it into the major/minor device code */
#define	X_major(x)  	(byte)((ushort)(x)>>8)
#define	X_minor(x)  	(byte)((x)&0377)

/* compose a dev_x from major/minor device code */
#define	X_makedev(x,y)	(dev_x)(((x)<<8)|(y))


/* Info about indirection blocks */
#define NINDIR	128		/* 128 indirection entries per block */
#define	NMASK	0177		/* i.e. (NINDIR-1) */
#define	NSHIFT	7		/* LOG2(NINDIR) */


#endif /*INO_H*/
